/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.imenu.terminal;


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Calendar;
import java.util.TreeMap;
import net.sf.json.JSONObject;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

public class TerminalContentServer extends ServerSocket {

    /**用来确认POS机有没有被注册。*/
    private static final String ValidTerminalURL = "http://localhost:8080/console/terminal?command=valid&terminalId=";
    //private static ArrayList userList = new ArrayList();
    private static TreeMap<Integer, ClientThread> clientThreads = new TreeMap<Integer, ClientThread>();
    private static int threadCounter = 0;
    protected static final int SERVER_PORT = 7000;
    //protected FileOutputStream LOG_FILE = new FileOutputStream("/content.log", true);

    private static TerminalContentServer INSTANCE;
    
    private TerminalContentServer() throws IOException {
        super(SERVER_PORT);
        System.out.println("....................... ...TerminalContentServer() SERVER_PORT = " + SERVER_PORT);
    }
    
    public static TerminalContentServer getInstance(){
        if(INSTANCE == null){
            try{
                INSTANCE = new TerminalContentServer();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        return INSTANCE;
    }
    
    public void sendMessageToClient(Integer storeId, String content){
        System.out.println("TerminalContentServer.sendMessageToClient() storeId="+storeId+" content="+content);
        System.out.println("TerminalContentServer.sendMessageToClient() clientThreads.keySet="+ clientThreads.keySet());
        clientThreads.get(storeId).sendMessage(content);
    }
    
    public void run() throws FileNotFoundException, IOException {
        System.out.println("TerminalContentServer.run().....................................0");
        Calendar now = Calendar.getInstance();
        String str = "[" + now.getTime().toString() + "] Accepted a connection\015\012";
        byte[] tmp = str.getBytes();
        //LOG_FILE.write(tmp);

        try {
            while (true) {
                System.out.println("TerminalContentServer.run().....................................1");
                Socket socket = accept();
                System.out.println("TerminalContentServer.run()....................................2.");
                new ClientThread(socket).start();
                System.out.println("TerminalContentServer.run().....................................3");
            }
        } finally {
            close();
        }
    }
    private boolean started = false;

    public void stop(){
        for(ClientThread clientThread : this.clientThreads.values()){
            clientThread.close();
        }
        try{
            close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    public void start() throws IOException {
        if (!started) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        INSTANCE.run();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
            started = true;
        }
    }

    class ClientThread extends Thread {

        private Socket clientSocket;
        private BufferedReader in;
        private PrintWriter out;
        private String Username;
        private Integer storeId;

        public ClientThread(Socket s) throws IOException {
            clientSocket = s;
            in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            String firstLine = in.readLine();
            if(firstLine != null) firstLine = firstLine.trim();
            System.out.println("TerminalContentServer.ClientThread() firstLine = "+firstLine);
            out = new PrintWriter(clientSocket.getOutputStream(), true);
            if (valid(firstLine)) {
                out.println("握手成功");
            }else{
                out.println("握手失败");
                throw new IOException("握手失败");
            }
        }

        /**访问服务器，验证POS有效性。*/
        private boolean valid(String terminalId) {
            String href = ValidTerminalURL + terminalId;
            HttpPost request = new HttpPost(href);
            System.out.println("TerminalContentServer.valie()! href="+href);
            try {
                HttpResponse httpResponse = new DefaultHttpClient().execute(request);
                String retSrc = EntityUtils.toString(httpResponse.getEntity(), "utf-8");
                System.out.println("TerminalContentServer.valie()! retSrc = " + retSrc);
                JSONObject jsonObject = JSONObject.fromObject(retSrc);
                boolean success = jsonObject.getBoolean("success");
                this.storeId = jsonObject.getInt("storeId");
                return success;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return false;
        }

        public void sendMessage(String msg) {
            System.out.println("TerminalContentServer.ClientThread.sendMessage() msg="+msg);
            out.println(msg);
        }

        @Override
        public void run() {
            try {
                threadCounter++;
                clientThreads.put(storeId, this);
                String line = in.readLine();
                while (!"bye".equals(line)) {
                    line = in.readLine();
                    //处理收到的信息：
                    System.out.println("ClientThread.run() line = "+line);
                    if(line == null) break;
                }
                clientSocket.close();
            } catch (IOException e) {
            } finally {
                try {
                    clientSocket.close();
                } catch (IOException e) {
                }
                threadCounter--;
                clientThreads.remove(storeId);
                //userList.remove(Username);
            }
        }
        
        public void close(){
            try{
                clientSocket.close();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}
